package com.som.service.excel;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.io.IOUtils;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

import com.som.beanconvert.ExcelColumnProcessInf;
import com.som.beanconvert.ExcelDataParseOutputInf;
import com.som.console.ErrorCode;
import com.som.console.ExcelProcException;

/**
 * 进行excel的写入到新的sheet页的数据操作
 * 
 * @author liujun
 * @date 2016年4月8日
 * @verion 0.0.1
 */
public abstract class ExcelWriteToSheetProcess<S, T>
{
	/**
	 * 通过过此抽换方法调用实现
	 * 
	 * @return
	 */
	protected abstract ExcelDataParseOutputInf<T> getToExcelInstall();

	/**
	 * 得到输出的列处理类
	 * 
	 * @return
	 */
	protected abstract ExcelColumnProcessInf getColumnInstall();

	/**
	 * 写入数据,从集合中
	 * 
	 * @param path
	 *            定入路径
	 * @param sheetName
	 *            sheet标签页名称
	 * @param cloumnMap
	 *            参数
	 * @param writeList
	 *            写入的集体
	 * @throws ExcelProcException
	 *             异常
	 */
	public void writeExcelByList(String path, String sheetName, Map<String, String> cloumnMap, List<T> writeList) throws ExcelProcException
	{
		POIFSFileSystem fs = null;

		// 创建一个工作薄
		HSSFWorkbook wb = null;
		// 创建sheet页
		HSSFSheet sheet = null;

		FileOutputStream output = null;
		try
		{
			fs = new POIFSFileSystem(new FileInputStream(path));
			// 得到Excel工作簿对象
			wb = new HSSFWorkbook(fs);
			// 创建一个新的sheet页
			sheet = wb.createSheet(sheetName);

			ExcelColumnProcessInf columnInatall = getColumnInstall();

			HSSFRow columnRow = sheet.createRow(0);

			// 进行首行列信息设置
			columnInatall.setExcelColumn(cloumnMap, columnRow);

			// 进行输出文件内容
			if (null != writeList && !writeList.isEmpty())
			{
				ExcelDataParseOutputInf<T> toExcelBean = getToExcelInstall();

				for (int i = 1; i < writeList.size(); i++)
				{
					HSSFRow row = sheet.createRow(i);

					toExcelBean.parseExcelRow(writeList.get(i), row);
				}
			}

			output = new FileOutputStream(path);

			wb.write(output);

			output.flush();

		} catch (FileNotFoundException e)
		{
			e.printStackTrace();
			throw new ExcelProcException(ErrorCode.FILE_NOTFOUNT.getMsg());
		} catch (IOException e)
		{
			e.printStackTrace();
			throw new ExcelProcException(ErrorCode.FILE_FILE_IS_ERROR.getMsg());
		} finally
		{
			IOUtils.closeQuietly(output);
			IOUtils.closeQuietly(wb);
			IOUtils.closeQuietly(fs);
		}
	}

	/**
	 * 写入excel数据，从map中读取
	 * 
	 * @param path
	 *            写入数据信息
	 * @param sheetName
	 *            sheet页名称
	 * @param cloumnMap
	 *            输入参数信息
	 * @param writeMAp
	 *            写入数据
	 * @throws ExcelProcException
	 */
	public void writeExcelByMap(String path, String sheetName, Map<String, String> cloumnMap, Map<S, T> writeMAp) throws ExcelProcException
	{
		POIFSFileSystem fs = null;

		// 创建一个工作薄
		HSSFWorkbook wb = null;
		// 创建sheet页
		HSSFSheet sheet = null;

		FileOutputStream output = null;
		try
		{
			fs = new POIFSFileSystem(new FileInputStream(path));
			// 得到Excel工作簿对象
			wb = new HSSFWorkbook(fs);
			// 创建一个新的sheet页
			sheet = wb.createSheet(sheetName);
			ExcelColumnProcessInf columnInatall = getColumnInstall();

			HSSFRow columnRow = sheet.createRow(0);

			// 进行首行列信息设置
			columnInatall.setExcelColumn(cloumnMap, columnRow);

			// 进行输出文件内容
			if (null != writeMAp && !writeMAp.isEmpty())
			{
				ExcelDataParseOutputInf<T> toExcelBean = getToExcelInstall();

				Iterator<Entry<S, T>> iterEntry = writeMAp.entrySet().iterator();

				Entry<S, T> item = null;

				int index = 1;
				while (iterEntry.hasNext())
				{
					item = iterEntry.next();

					HSSFRow row = sheet.createRow(index);
					toExcelBean.parseExcelRow(item.getValue(), row);

					index++;
				}
			}

			output = new FileOutputStream(path);

			wb.write(output);

			output.flush();

		} catch (FileNotFoundException e)
		{
			e.printStackTrace();
			throw new ExcelProcException(ErrorCode.FILE_NOTFOUNT.getMsg());
		} catch (IOException e)
		{
			e.printStackTrace();
			throw new ExcelProcException(ErrorCode.FILE_FILE_IS_ERROR.getMsg());
		} finally
		{
			IOUtils.closeQuietly(output);
			IOUtils.closeQuietly(wb);
			IOUtils.closeQuietly(fs);
		}
	}
}
